package com.example.wenmini.service.QsFill;

import com.example.wenmini.service.humanlike.HumanLikeOperator;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.*;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;


@Service
@Slf4j
public class Submit {

    @Autowired
    private HumanLikeOperator humanLikeOperator;




    public boolean submitQuestionnaireWithRetry(WebDriver driver, Long taskId) {
        int maxRetries = 1;
        for (int i = 0; i < maxRetries; i++) {
            try {
                log.info("开始提交问卷，第{}次尝试", i + 1);
                // 首先尝试直接提交
                if (submitQuestionnaire(driver, taskId)) {
                    log.info("问卷提交成功");
                    return true;
                }

                // 如果提交失败，检查是否需要处理智能验证
                try {
                    if (checkSmartVerification(driver)) {
                        log.info("检测到智能验证，开始处理");
                        handleSmartVerification(driver, taskId);

                        // 再次尝试提交
                        if (submitQuestionnaire(driver, taskId)) {
                            log.info("智能验证后提交成功");
                            return true;
                        }
                    }
                } catch (Exception e) {
                    // 检查是否是会话失效错误
                    if (isSessionInvalidError(e)) {
                        log.error("浏览器会话已失效，终止重试");
                        return false;
                    }
                    log.warn("检查智能验证时出错：{}", e.getMessage());
                }

                if (i < maxRetries - 1) {
                    Thread.sleep(3000);
                }
            } catch (Exception e) {

                // 检查是否是会话失效错误
                if (isSessionInvalidError(e)) {
                    log.error("浏览器会话已失效，终止重试");
                    return false;
                }

                log.error("提交过程出错：{}", e.getMessage());
                if (i < maxRetries - 1) {
                    log.info("等待3秒后重试");
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        return false;
                    }
                }
            }
        }
        return false;
    }

    private boolean isSessionInvalidError(Exception e) {
        String message = e.getMessage();
        if (message == null) return false;

        return message.contains("invalid session id") ||
                message.contains("session deleted") ||
                message.contains("connection reset") ||
                message.contains("browser has closed the connection");
    }

    private boolean submitQuestionnaire(WebDriver driver, Long taskId) {
        try {
            log.info("等待页面元素加载...");
            // 查找提交按钮
            WebElement submitButton = findSubmitButton(driver, taskId);
            if (submitButton == null) {
                log.error("未找到提交按钮");

                return false;
            }

            // 检查按钮是否仍然有效
            try {
                submitButton.isEnabled();
            } catch (StaleElementReferenceException e) {
                log.warn("提交按钮元素已失效，尝试重新查找");
                submitButton = findSubmitButton(driver, taskId);
                if (submitButton == null) {
                    log.error("重新查找提交按钮失败");
                    return false;
                }
            }

            // 滚动到提交按钮
            log.info("开始滚动到提交按钮位置...");
            long scrollStart = System.currentTimeMillis();
            try {
                ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView({behavior: 'smooth', block: 'center'});", submitButton);
                Thread.sleep(500); // 等待滚动完成
                log.info("滚动完成，耗时：{}ms", System.currentTimeMillis() - scrollStart);
            } catch (Exception e) {
                log.warn("滚动到提交按钮时出错：{}", e.getMessage());
            }

            // 点击提交按钮
            log.info("开始执行点击操作...");
            long clickStart = System.currentTimeMillis();
            try {
                // 先尝试使用JavaScript点击
                ((JavascriptExecutor) driver).executeScript("arguments[0].click();", submitButton);
            } catch (Exception e) {
                log.warn("JavaScript点击失败，尝试普通点击：{}", e.getMessage());
                submitButton.click();
            }
            log.info("点击操作完成，耗时：{}ms", System.currentTimeMillis() - clickStart);

            // 等待提交结果
            log.info("等待提交结果...");
            long totalStart = System.currentTimeMillis();
            WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));

            // 封装带计时的条件检查
            class TimedCondition implements ExpectedCondition<Boolean> {
                private final String conditionName;
                private final ExpectedCondition<Boolean> delegate;

                TimedCondition(String name, ExpectedCondition<Boolean> delegate) {
                    this.conditionName = name;
                    this.delegate = delegate;
                }

                @Override
                public Boolean apply(WebDriver driver) {
                    long start = System.currentTimeMillis();
                    try {
                        Boolean result = delegate.apply(driver);
                        long cost = System.currentTimeMillis() - start;
                        log.debug("[条件检查] {} => {} (耗时:{}ms)", conditionName, result, cost);
                        return result;
                    } catch (Exception e) {
                        long cost = System.currentTimeMillis() - start;
                        log.debug("[条件检查] {} => 失败 (耗时:{}ms, 原因: {})", conditionName, cost, e.getMessage());
                        return false;
                    }
                }
            }

            // 构建带计时的条件集合
            List<ExpectedCondition<Boolean>> conditions = Arrays.asList(
                    new TimedCondition("URL包含'complete'", ExpectedConditions.urlContains("complete")),
                    new TimedCondition("URL包含'complete'", ExpectedConditions.urlContains("complete")),
                    new TimedCondition("URL包含'success'", ExpectedConditions.urlContains("success")),
                    new TimedCondition("URL包含'thanks'", ExpectedConditions.urlContains("thank"))
            );

            try {
                // 逐个检查条件直到成功或超时
                for (ExpectedCondition<Boolean> condition : conditions) {
                    long conditionStart = System.currentTimeMillis();
                    try {
                        Boolean result = wait.until(condition);
                        if (result != null && result) {
                            long totalCost = System.currentTimeMillis() - totalStart;
                            log.info("✅ 通过条件 [{}] 检测到提交成功，总耗时：{}ms",
                                    ((TimedCondition)condition).conditionName, totalCost);
                            return true;
                        }
                    } catch (TimeoutException e) {
                        long conditionCost = System.currentTimeMillis() - conditionStart;
                        log.warn("⏰ 条件 [{}] 检查超时，耗时：{}ms",
                                ((TimedCondition)condition).conditionName, conditionCost);
                    }
                }

                log.error("所有条件检查均未通过，总耗时：{}ms", System.currentTimeMillis() - totalStart);
                return false;
            } catch (Exception e) {
                log.error("❌ 异常终止，总耗时：{}ms，原因：{}",
                        System.currentTimeMillis() - totalStart, e.getMessage());
                return false;
            }

        } catch (Exception e) {
            return false;
        }
    }

    private WebElement findSubmitButton(WebDriver driver, Long taskId) {
        log.info("开始查找提交按钮...");
        long startTime = System.currentTimeMillis();

        // 等待页面加载完成
        try {
            Thread.sleep(300);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }

        // 可能的提交按钮选择器
        String[] submitSelectors = {
                "#ctlNext",
                "#submit_button",
                "#btnSubmit",
                "#divSubmit",
                "#btnNext",
                "#btnSave",
                "#btnUpload",
                "input[type='submit']",
                "button[type='submit']",
                ".submitbutton",
                ".submit-button",
                ".next-button",
                "[class*='submit']",
                "[id*='submit']",
                "[class*='next']",
                "[id*='next']",
                "button.btn-primary",
                "input.btn-primary"
        };

        WebElement submitButton = null;
        int selectorIndex = 0;

        // 尝试每个选择器
        for (String selector : submitSelectors) {
            selectorIndex++;
            try {
                log.debug("尝试第{}个选择器: {}", selectorIndex, selector);
                List<WebElement> elements = driver.findElements(By.cssSelector(selector));
                for (WebElement element : elements) {
                    if (element.isDisplayed() && (
                            element.getText().toLowerCase().contains("submit") ||
                                    element.getText().contains("提交") ||
                                    element.getText().contains("下一步") ||
                                    element.getAttribute("value") != null && (
                                            Objects.requireNonNull(element.getAttribute("value")).contains("提交") ||
                                                    Objects.requireNonNull(element.getAttribute("value")).contains("下一步")
                                    ) ||
                                    "submit_button".equals(element.getAttribute("id")) ||
                                    "submitbutton".equals(element.getAttribute("class"))
                    )) {
                        submitButton = element;
                        log.info("在第{}个选择器找到提交按钮", selectorIndex);
                        break;
                    }
                }
                if (submitButton != null) {
                    break;
                }
            } catch (Exception ignored) {
                // 继续尝试下一个选择器
            }
        }

        // 如果还是没找到，尝试通过XPath查找包含相关文本的元素
        if (submitButton == null) {
            log.info("CSS选择器未找到按钮，尝试XPath查找...");
            try {
                List<WebElement> elements = driver.findElements(
                        By.xpath("//*[contains(text(), '提交') or contains(@value, '提交') or " +
                                "contains(text(), '下一步') or contains(@value, '下一步')]")
                );
                for (WebElement element : elements) {
                    if (element.isDisplayed()) {
                        submitButton = element;
                        log.info("通过XPath找到提交按钮");
                        break;
                    }
                }
            } catch (Exception ignored) {
                // 忽略异常
            }
        }

        log.info("查找提交按钮{}，耗时：{}ms",
                submitButton != null ? "成功" : "失败",
                System.currentTimeMillis() - startTime);

        return submitButton;
    }

    private void handleSmartVerification(WebDriver driver, Long taskId) {
        try {
            humanLikeOperator.handleSmartVerification(driver);
        } catch (Exception e) {
            throw e;
        }
    }

    private boolean checkSmartVerification(WebDriver driver) {
        try {
            // 检查常见的验证码元素
            String[] verifySelectors = {
                    ".verify-wrap", "#verify-wrap",
                    ".captcha", "#captcha",
                    ".verification", "#verification",
                    "iframe[src*='verify']",
                    "iframe[src*='captcha']",
                    ".slideverify",
                    "#sliderVerify"
            };

            for (String selector : verifySelectors) {
                List<WebElement> elements = driver.findElements(By.cssSelector(selector));
                if (!elements.isEmpty() && elements.get(0).isDisplayed()) {
                    log.warn("检测到智能验证元素：{}", selector);
                    return true;
                }
            }

            return false;
        } catch (Exception e) {
            log.warn("检查智能验证时出错：{}", e.getMessage());
            return false;
        }
    }

}
